package com.ymx.darling.spring.boot.autoconfigure;

import javax.sql.DataSource;

import com.ymx.darling.bean.entity.BeanInfoManager;
import com.ymx.darling.bean.entity.dynamic.DynamicSchemaProcessor;
import com.ymx.darling.bean.entity.dynamic.DynamicTableProcessor;
import com.ymx.darling.bean.entity.fill.EntityFillProcessor;
import com.ymx.darling.intercept.ExecutorInterceptor;
import com.ymx.darling.intercept.InterceptManager;
import com.ymx.darling.logicdelete.LogicDeleteManager;
import com.ymx.darling.logicdelete.LogicDeleteProcessor;
import com.ymx.darling.session.SessionFactory;
import com.ymx.darling.spring.mapper.SessionFactoryBean;
import com.ymx.darling.tenant.TenantFactory;
import com.ymx.darling.tenant.TenantManager;
import com.ymx.darling.wrapper.UpdateWrapper;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;
import java.util.function.Consumer;

/**
 * Darling自动配置类，用于自动配置Darling相关的组件
 * @author 爱Java的小于
 */
@Configuration
// 当SessionFactory和SessionFactoryBean类存在时，才加载该配置类
@ConditionalOnClass({SessionFactory.class, SessionFactoryBean.class})
// 当只有一个DataSource候选 bean 时，才加载该配置类
@ConditionalOnSingleCandidate(DataSource.class)
// 启用Darling属性配置
@EnableConfigurationProperties({DarlingProperties.class})
// 在DataSource自动配置之后加载该配置类
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class DarlingAutoConfiguration {
    private final DarlingProperties properties;

    private final DarlingCustomizer darlingCustomizer;

    /**
     * 构造函数，初始化DarlingAutoConfiguration
     *
     * @param properties Darling属性配置
     */
    public DarlingAutoConfiguration(DarlingProperties properties, ObjectProvider<DarlingCustomizer> darlingCustomizerObjectProvider) {
        this.properties = properties;
        this.darlingCustomizer = darlingCustomizerObjectProvider.getIfAvailable();
    }

    /**
     * 创建并配置SessionFactory bean
     *
     * @param dataSource 数据源
     * @return SessionFactory实例
     */
    @Bean
    // 当Spring上下文中没有SessionFactory bean时，才创建该bean
    @ConditionalOnMissingBean
    public SessionFactory sessionFactory(DataSource dataSource) {
        SessionFactoryBean factory = new SessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setLogImpl(properties.getLogImpl());
        factory.setCacheEnabled(this.properties.isCacheEnabled());
        factory.setEntityPackage(this.properties.getEntityPackage());
        factory.setMapperLocation(this.properties.getMapperLocations());
        // 判断用户自定义了初始化配置
        if (this.darlingCustomizer != null) {
            // 注册Executor拦截器
            ExecutorInterceptor executorInterceptor = this.darlingCustomizer.getExecutorInterceptor();
            if (executorInterceptor != null) {
                InterceptManager.registerExecutorInterceptor(executorInterceptor);
            }
            // 设置租户工厂实例
            TenantFactory tenantFactory = this.darlingCustomizer.getTenantFactory();
            if (tenantFactory != null) {
                TenantManager.setTenantFactory(tenantFactory);
            }
            // 注册动态表名处理器
            DynamicTableProcessor dynamicTableProcessor = this.darlingCustomizer.getDynamicTableProcessor();
            if (dynamicTableProcessor != null) {
                BeanInfoManager.registerDynamicTableProcessor(dynamicTableProcessor);
            }
            // 注册动态schema处理器
            DynamicSchemaProcessor dynamicSchemaProcessor = this.darlingCustomizer.getDynamicSchemaProcessor();
            if (dynamicSchemaProcessor != null) {
                BeanInfoManager.registerDynamicSchemaProcessor(dynamicSchemaProcessor);
            }
            // 注册后置逻辑处理器
            Consumer<UpdateWrapper> afterSetLogicDeleteProcessor = this.darlingCustomizer.registerAfterSetLogicDeleteProcessor();
            if (afterSetLogicDeleteProcessor != null) {
                LogicDeleteManager.registerAfterSetLogicDeleteProcessor(afterSetLogicDeleteProcessor);
            }
            // 注册实体填充处理器
            EntityFillProcessor entityFillProcessor = this.darlingCustomizer.getEntityFillProcessor();
            if (entityFillProcessor != null) {
                BeanInfoManager.registerEntityFillProcessor(entityFillProcessor);
            }
            // 注册逻辑删除处理器
            Map<Class<?>, LogicDeleteProcessor> logicDeleteProcessorMap = this.darlingCustomizer.getLogicDeleteProcessorMap();
            if (logicDeleteProcessorMap != null) {
                logicDeleteProcessorMap.forEach(LogicDeleteManager::registerLogicDeleteProcessor);
            }
        }

        return factory.getObject();
    }
}
